import React from "react";
import * as echarts from "echarts";
import BaseEcharts from "../BaseEcharts";
import dataConvertInstance from "../../lib/dataConvert";
import mapRegisterInstance from "../../lib/mapRegister";
import "echarts/lib/component/grid";

interface IReactForEchartsProps {
  options: any;
  dataSourceConfig: Array<any>;
  geoMap?: Array<any>;
  eventsMap?: any;
}
interface IReactForEchartsState {
  options: any;
}
export default class ReactForEcharts extends React.Component<IReactForEchartsProps, IReactForEchartsState> {
  private echartsInstance: echarts.ECharts | undefined;
  constructor(props: IReactForEchartsProps) {
    super(props);
    this.state = {
      options: null,
    }
  }
  registerMap = (geoMap: any) => {
    if (!geoMap) return;
    mapRegisterInstance.registerMap(geoMap);
  }
  mergeDataToOptions = (props: IReactForEchartsProps) => {
    const { options, dataSourceConfig } = props;
    this.setState({ options: null });
    const dataSource = dataSourceConfig.map(async data => await dataConvertInstance.convertData(data));
    Promise.all(dataSource).then(allData => {
      const series = options.series;
      if (Array.isArray(series)) {
        series.forEach((item, index) => {
          item.data = allData?.[index] || item?.data || [];
        })
      }
      this.setState({ options: options });
    })
  }
  componentDidMount() {
    this.registerMap(this.props.geoMap);
    this.mergeDataToOptions(this.props);
  }
  shouldComponentUpdate(nextProps: IReactForEchartsProps, nextState: any) {
    if (nextProps.geoMap !== this.props.geoMap) {
      this.registerMap(nextProps.geoMap);
    }
    if (nextProps.options !== this.props.options || nextProps.dataSourceConfig !== this.props.dataSourceConfig) {
      this.mergeDataToOptions(nextProps);
    }
    if (nextProps.eventsMap !== this.props.eventsMap) {
      Object.keys(nextProps.eventsMap || {}).forEach(key => {
        nextProps.eventsMap[key] && this.echartsInstance?.on(key, nextProps.eventsMap[key])
      })
    }
    if (nextProps !== this.props || nextState !== this.state) return true;
    return false;
  }
  dispatchAction(actionName: string, params: any) {
    this.echartsInstance?.dispatchAction({
      type: actionName,
      ...params
    })
  }
  saveEchartsInstance = (echartsInstance: echarts.ECharts) => {
    const { eventsMap } = this.props;
    this.echartsInstance = echartsInstance;
    Object.keys(eventsMap || {}).forEach(key => {
      this.echartsInstance?.on(key, eventsMap[key])
    })
  }
  render() {
    const { options } = this.state;
    return options ? <BaseEcharts option={options} echartsInstance={this.saveEchartsInstance} /> : "Loading...";
  }
}